#include "stdafx.h"
#include "VertexBufferPart.h"

#include "../mesh/Mesh.h"
#include "../mesh/MeshPart.h"
#include "../mesh/VertexStream.h"
#include "VertexBuffer.h"

namespace WindGE
{
	VertexBufferPart::VertexBufferPart()
		: render_device_(nullptr)
		, ib_(nullptr)
	{
	}

	VertexBufferPart::~VertexBufferPart()
	{
	}

	bool VertexBufferPart::init(RenderDevicePtr renderDevice, std::initializer_list<bool> isDynamicVec, 
								bool hasIndex /* = true */, bool indexDynamic /* = false */)
	{
		render_device_ = renderDevice;
		for (auto iter = isDynamicVec.begin(); iter != isDynamicVec.end(); ++iter)
		{
			VertexBufferPtr vb = std::make_shared<VertexBuffer>();
			if (!vb->init(renderDevice, evb_vertex, *iter)) return false;
			vb_list_.push_back(vb);
		}

		if (hasIndex)
		{
			ib_ = std::make_shared<VertexBuffer>();
			if (!ib_->init(renderDevice, evb_index, indexDynamic)) return false;
		}

		return true;
	}

	bool VertexBufferPart::build(MeshPartPtr meshPart)
	{
		vs_names_.clear();
		part_info_ = meshPart->part_info();

		for (unsigned int i = 0; i < vb_list_.size(); ++i)
		{
			meshPart->visit_stream_mapping([i, this](VertexStreamPair vsPair)
			{
				VertexStreamPtr vstream = vsPair.second;
				if (!vstream->is_index())
				{
					vs_names_.insert({ vsPair.first, i });
					vb_list_[i]->build(vstream->buffer(), vstream->stride(), vstream->count());
				}
				else
				{
					ib_->build(vstream->buffer(), vstream->stride(), vstream->count());
				}
			});
		}

		return true;
	}

	void VertexBufferPart::bind_vertex_buffer(unsigned int slot, unsigned int offset)
	{
		if (slot < 0 || slot >= vb_list_.size()) return;

		vb_list_[slot]->bind_vertex(slot, offset);
	}

	void VertexBufferPart::bind_vertex_buffer(const std::string& slotName, unsigned int offset)
	{
		auto iter = vs_names_.find(slotName);
		if (iter != vs_names_.end())
		{
			vb_list_[iter->second]->bind_vertex(iter->second, offset);
		}
	}

	void VertexBufferPart::bind_index_buffer(unsigned int offset)
	{
		ib_->bind_index(offset);
	}

	bool VertexBufferPart::update_vertex_buffer(unsigned int slot, unsigned int size, void* datas)
	{
		return true;
	}

	bool VertexBufferPart::update_index_buffer(unsigned int size, void* datas)
	{
		return true;
	}

}//end namespace WindGE

